from glob import glob
import os.path
import sys

osName = sys.platform[:3]

def enumerateFiles(pattern, path = '.'):
    if not path.startswith('./libs'):
        files = filter(os.path.isfile,glob(path + '/' + pattern))
        for subPath in filter(os.path.isdir,glob(path + '/*')):
            files.extend(enumerateFiles(pattern,subPath))
        return files
    else:
        return []
    
files = enumerateFiles('*')

filesByType = {}
pathsByType = {}
for file in files:
    fileType = file.split('.')[-1]
    filePath = file[:file.rfind('/')]
    filesByType.setdefault(fileType,[]).append(file)
    pathsByType.setdefault(fileType,set()).add(filePath)
    
sources = filter(lambda file: not file.startswith('./server') and 'actionFactory.cpp' not in file, filesByType['cpp'])
includeDirs = list(pathsByType['h']) + ['.']
libs = []
libDirs = []

actions = {}

prefixes = ['///sdse_%s_' % osName, '///sdse_']
for file in filesByType['h']:
    for line in open(file).readlines():
        for prefix in prefixes:
            if line.startswith(prefix):
                prefixOp, arg = line.split()[:2]
                op = prefixOp[len(prefix):]
                
                if op == 'action':
                    actions[arg] = file
                    break
                elif op == 'includeDir':
                    includeDirs.append(arg)
                    break
                elif op == 'libDir':
                    libDirs.append(arg)
                    break
                elif op == 'lib':
                    libs.append(arg)
                    break
                else:
                    print "ERROR: unknown header arg %s" % op

actionFactory = open('system/actionFactory.cpp','w')
actionFactory.write('#include "object.h"\n')

for file in actions.itervalues():
    actionFactory.write('#include "%s"\n' % file)

actionFactory.write("namespace sde {\n")
actionFactory.write("Action* Object::actionFactory(std::string actionType, std::string actionName) {\n")

for action, file in actions.iteritems():
    path = file.lstrip('./')
    path = path[:path.rfind('/')+1]
    actionType = path + action
    actionFactory.write('    if (actionType == "%s") return new %s(actionType,actionName,this);\n' % (actionType,action))

actionFactory.write('    return 0;\n}\n}\n')

actionFactory.close()

sources.append('system/actionFactory.cpp')

p = Program(target = 'main', source = sources, CPPPATH = includeDirs, LIBS = libs, LIBPATH = libDirs)
Clean(p,'system/actionFactory.cpp')
